package com.pancm.datacollector.forwarder.impl;

import com.pancm.datacollector.forwarder.DataForwarder;
import com.pancm.datacollector.forwarder.ForwarderConfig;
import com.pancm.datacollector.forwarder.ForwarderStatus;
import com.pancm.datacollector.forwarder.ForwarderProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReentrantLock;

/**
 * HTTP协议数据转发器
 * 线程安全的实现
 */
@Component
public class HttpDataForwarder implements DataForwarder {
    private static final Logger LOG = LoggerFactory.getLogger(HttpDataForwarder.class);
    
    private final RestTemplate restTemplate;
    private final AtomicReference<ForwarderStatus> status;
    private final AtomicReference<ForwarderConfig> config;
    private final AtomicInteger successCount;
    private final AtomicInteger failureCount;
    private final ReentrantLock configLock;
    
    @Autowired
    private ForwarderProperties properties;
    
    private HttpHeaders headers;
    
    public HttpDataForwarder() {
        this.restTemplate = new RestTemplate();
        this.status = new AtomicReference<>(ForwarderStatus.UNINIT);
        this.config = new AtomicReference<>(new ForwarderConfig());
        this.successCount = new AtomicInteger(0);
        this.failureCount = new AtomicInteger(0);
        this.configLock = new ReentrantLock();
        this.headers = new HttpHeaders();
    }
    
    @PostConstruct
    public void init() {
        LOG.info("初始化HTTP数据转发器...");
        
        // 从配置文件初始化 ForwarderConfig
        ForwarderConfig initialConfig = new ForwarderConfig();
        initialConfig.setProtocol(properties.getHttp().getProtocol());
        initialConfig.setServerHost(properties.getHttp().getServerHost());
        initialConfig.setServerPort(properties.getHttp().getServerPort());
        initialConfig.setParameters(properties.getHttp().getParameters());
        
        // 更新配置
        config.set(initialConfig);
        
        // 初始化headers
        headers.setContentType(MediaType.APPLICATION_JSON);
        updateHttpConfig(initialConfig);
        
        status.set(ForwarderStatus.RUNNING);
        
        LOG.info("HTTP数据转发器初始化完成, 目标地址: {}:{}", 
            initialConfig.getServerHost(), 
            initialConfig.getServerPort());
    }
    
    @Override
    public void forward(HashMap<String, Object> data) throws Exception {
        if (status.get() != ForwarderStatus.RUNNING) {
            throw new IllegalStateException("转发器未处于运行状态");
        }
        
        ForwarderConfig currentConfig = config.get();
        String url = buildTargetUrl(currentConfig);
        
        try {
            HttpEntity<HashMap<String, Object>> request = new HttpEntity<>(data, headers);
            
            // 发送HTTP请求
            ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class);
            
            if (response.getStatusCode().is2xxSuccessful()) {
                successCount.incrementAndGet();
                LOG.debug("数据转发成功, URL: {}, Response: {}", url, response.getBody());
            } else {
                failureCount.incrementAndGet();
                LOG.error("数据转发失败, URL: {}, Status: {}", url, response.getStatusCode());
                throw new Exception("HTTP请求返回非成功状态码: " + response.getStatusCode());
            }
            
        } catch (Exception e) {
            failureCount.incrementAndGet();
            LOG.error("数据转发异常, URL: {}", url, e);
            throw e;
        }
    }
    
    @Override
    public ForwarderStatus getStatus() {
        return status.get();
    }
    
    @Override
    public ForwarderConfig getConfig() {
        return config.get();
    }
    
    @Override
    public void updateConfig(ForwarderConfig newConfig) throws Exception {
        configLock.lock();
        try {
            LOG.info("更新转发器配置...");
            
            // 验证配置
            validateConfig(newConfig);
            
            // 更新配置
            config.set(newConfig);
            
            // 更新HTTP相关配置
            updateHttpConfig(newConfig);
            
            LOG.info("转发器配置更新完成");
        } finally {
            configLock.unlock();
        }
    }
    
    /**
     * 构建目标URL
     */
    private String buildTargetUrl(ForwarderConfig config) {
        return String.format("http://%s:%d%s",
            config.getServerHost(),
            config.getServerPort(),
            config.getParameters().getOrDefault("path", "/"));
    }
    
    /**
     * 验证配置
     */
    private void validateConfig(ForwarderConfig config) throws Exception {
        if (!"http".equalsIgnoreCase(config.getProtocol())) {
            throw new Exception("不支持的协议类型: " + config.getProtocol());
        }
        
        if (config.getServerHost() == null || config.getServerHost().isEmpty()) {
            throw new Exception("服务器地址不能为空");
        }
        
        if (config.getServerPort() <= 0 || config.getServerPort() > 65535) {
            throw new Exception("无效的端口号: " + config.getServerPort());
        }
    }
    
    /**
     * 更新HTTP相关配置
     */
    private void updateHttpConfig(ForwarderConfig config) {
        Map<String, Object> params = config.getParameters();
        if (params != null) {
            // 更新请求头
            if (params.containsKey("headers")) {
                @SuppressWarnings("unchecked")
                Map<String, String> headerMap = (Map<String, String>) params.get("headers");
                headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_JSON);
                headerMap.forEach(headers::add);
            }
        }
    }
    
    /**
     * 获取成功转发次数
     */
    public int getSuccessCount() {
        return successCount.get();
    }
    
    /**
     * 获取失败转发次数
     */
    public int getFailureCount() {
        return failureCount.get();
    }
} 